1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.base.Function;
21 import com.google.common.base.Functions;
22 import com.google.common.collect.testing.MapInterfaceTest;
23
24 import java.util.Collection;
25 import java.util.Iterator;
26 import java.util.Map;
27 import java.util.Set;
28
29 import javax.annotation.Nullable;
30
31
32
33
34
35
36
37 @GwtCompatible
38 public class MapsTransformValuesUnmodifiableIteratorTest extends MapInterfaceTest<String, String> {
39
40
41
42 public MapsTransformValuesUnmodifiableIteratorTest() {
43 super(true, true, false , true, true, false);
44 }
45
46 private static class UnmodifiableIteratorMap<K, V> extends ForwardingMap<K, V> {
47 final Map<K, V> delegate;
48
49 UnmodifiableIteratorMap(Map<K, V> delegate) {
50 this.delegate = delegate;
51 }
52
53 @Override protected Map<K, V> delegate() {
54 return delegate;
55 }
56
57 @Override public Set<K> keySet() {
58 return new ForwardingSet<K>() {
59 @Override protected Set<K> delegate() {
60 return delegate.keySet();
61 }
62 @Override public Iterator<K> iterator() {
63 return Iterators.unmodifiableIterator(delegate.keySet().iterator());
64 }
65 @Override public boolean removeAll(Collection<?> c) {
66 return delegate.keySet().removeAll(c);
67 }
68 @Override public boolean retainAll(Collection<?> c) {
69 return delegate.keySet().retainAll(c);
70 }
71 };
72 }
73
74 @Override public Collection<V> values() {
75 return new ForwardingCollection<V>() {
76 @Override protected Collection<V> delegate() {
77 return delegate.values();
78 }
79 @Override public Iterator<V> iterator() {
80 return Iterators.unmodifiableIterator(delegate.values().iterator());
81 }
82 @Override public boolean removeAll(Collection<?> c) {
83 return delegate.values().removeAll(c);
84 }
85 @Override public boolean retainAll(Collection<?> c) {
86 return delegate.values().retainAll(c);
87 }
88 };
89 }
90
91 @Override public Set<Entry<K, V>> entrySet() {
92 return new ForwardingSet<Entry<K, V>>() {
93 @Override protected Set<Entry<K, V>> delegate() {
94 return delegate.entrySet();
95 }
96 @Override public Iterator<Entry<K, V>> iterator() {
97 return Iterators.unmodifiableIterator(delegate.entrySet().iterator());
98 }
99 @Override public boolean removeAll(Collection<?> c) {
100 return delegate.entrySet().removeAll(c);
101 }
102 @Override public boolean retainAll(Collection<?> c) {
103 return delegate.entrySet().retainAll(c);
104 }
105 };
106 }
107 }
108
109 @Override protected Map<String, String> makeEmptyMap() {
110 Map<String, Integer> underlying = Maps.newHashMap();
111 return Maps.transformValues(
112 new UnmodifiableIteratorMap<String, Integer>(underlying), Functions.toStringFunction());
113 }
114
115 @Override protected Map<String, String> makePopulatedMap() {
116 Map<String, Integer> underlying = Maps.newHashMap();
117 underlying.put("a", 1);
118 underlying.put("b", 2);
119 underlying.put("c", 3);
120 return Maps.transformValues(
121 new UnmodifiableIteratorMap<String, Integer>(underlying), Functions.toStringFunction());
122 }
123
124 @Override protected String getKeyNotInPopulatedMap()
125 throws UnsupportedOperationException {
126 return "z";
127 }
128
129 @Override protected String getValueNotInPopulatedMap()
130 throws UnsupportedOperationException {
131 return "26";
132 }
133
134
135 private void assertMapsEqual(Map<?, ?> expected, Map<?, ?> map) {
136 assertEquals(expected, map);
137 assertEquals(expected.hashCode(), map.hashCode());
138 assertEquals(expected.entrySet(), map.entrySet());
139
140
141
142 Collection<?> expectedValues = expected.values();
143 Collection<?> mapValues = map.values();
144 assertEquals(expectedValues.size(), mapValues.size());
145 assertTrue(expectedValues.containsAll(mapValues));
146 assertTrue(mapValues.containsAll(expectedValues));
147 }
148
149 public void testTransformEmptyMapEquality() {
150 Map<String, String> map = Maps.transformValues(
151 ImmutableMap.<String, Integer>of(), Functions.toStringFunction());
152 assertMapsEqual(Maps.newHashMap(), map);
153 }
154
155 public void testTransformSingletonMapEquality() {
156 Map<String, String> map = Maps.transformValues(
157 ImmutableMap.of("a", 1), Functions.toStringFunction());
158 Map<String, String> expected = ImmutableMap.of("a", "1");
159 assertMapsEqual(expected, map);
160 assertEquals(expected.get("a"), map.get("a"));
161 }
162
163 public void testTransformIdentityFunctionEquality() {
164 Map<String, Integer> underlying = ImmutableMap.of("a", 1);
165 Map<String, Integer> map = Maps.transformValues(
166 underlying, Functions.<Integer>identity());
167 assertMapsEqual(underlying, map);
168 }
169
170 public void testTransformPutEntryIsUnsupported() {
171 Map<String, String> map = Maps.transformValues(
172 ImmutableMap.of("a", 1), Functions.toStringFunction());
173 try {
174 map.put("b", "2");
175 fail();
176 } catch (UnsupportedOperationException expected) {
177 }
178
179 try {
180 map.putAll(ImmutableMap.of("b", "2"));
181 fail();
182 } catch (UnsupportedOperationException expected) {
183 }
184
185 try {
186 map.entrySet().iterator().next().setValue("one");
187 fail();
188 } catch (UnsupportedOperationException expected) {
189 }
190 }
191
192 public void testTransformRemoveEntry() {
193 Map<String, Integer> underlying = Maps.newHashMap();
194 underlying.put("a", 1);
195 Map<String, String> map
196 = Maps.transformValues(underlying, Functions.toStringFunction());
197 assertEquals("1", map.remove("a"));
198 assertNull(map.remove("b"));
199 }
200
201 public void testTransformEqualityOfMapsWithNullValues() {
202 Map<String, String> underlying = Maps.newHashMap();
203 underlying.put("a", null);
204 underlying.put("b", "");
205
206 Map<String, Boolean> map = Maps.transformValues(underlying,
207 new Function<String, Boolean>() {
208 @Override
209 public Boolean apply(@Nullable String from) {
210 return from == null;
211 }
212 }
213 );
214 Map<String, Boolean> expected = ImmutableMap.of("a", true, "b", false);
215 assertMapsEqual(expected, map);
216 assertEquals(expected.get("a"), map.get("a"));
217 assertEquals(expected.containsKey("a"), map.containsKey("a"));
218 assertEquals(expected.get("b"), map.get("b"));
219 assertEquals(expected.containsKey("b"), map.containsKey("b"));
220 assertEquals(expected.get("c"), map.get("c"));
221 assertEquals(expected.containsKey("c"), map.containsKey("c"));
222 }
223
224 public void testTransformReflectsUnderlyingMap() {
225 Map<String, Integer> underlying = Maps.newHashMap();
226 underlying.put("a", 1);
227 underlying.put("b", 2);
228 underlying.put("c", 3);
229 Map<String, String> map
230 = Maps.transformValues(underlying, Functions.toStringFunction());
231 assertEquals(underlying.size(), map.size());
232
233 underlying.put("d", 4);
234 assertEquals(underlying.size(), map.size());
235 assertEquals("4", map.get("d"));
236
237 underlying.remove("c");
238 assertEquals(underlying.size(), map.size());
239 assertFalse(map.containsKey("c"));
240
241 underlying.clear();
242 assertEquals(underlying.size(), map.size());
243 }
244
245 public void testTransformChangesAreReflectedInUnderlyingMap() {
246 Map<String, Integer> underlying = Maps.newLinkedHashMap();
247 underlying.put("a", 1);
248 underlying.put("b", 2);
249 underlying.put("c", 3);
250 underlying.put("d", 4);
251 underlying.put("e", 5);
252 underlying.put("f", 6);
253 underlying.put("g", 7);
254 Map<String, String> map
255 = Maps.transformValues(underlying, Functions.toStringFunction());
256
257 map.remove("a");
258 assertFalse(underlying.containsKey("a"));
259
260 Set<String> keys = map.keySet();
261 keys.remove("b");
262 assertFalse(underlying.containsKey("b"));
263
264 Iterator<String> keyIterator = keys.iterator();
265 keyIterator.next();
266 keyIterator.remove();
267 assertFalse(underlying.containsKey("c"));
268
269 Collection<String> values = map.values();
270 values.remove("4");
271 assertFalse(underlying.containsKey("d"));
272
273 Iterator<String> valueIterator = values.iterator();
274 valueIterator.next();
275 valueIterator.remove();
276 assertFalse(underlying.containsKey("e"));
277
278 Set<Map.Entry<String, String>> entries = map.entrySet();
279 Map.Entry<String, String> firstEntry = entries.iterator().next();
280 entries.remove(firstEntry);
281 assertFalse(underlying.containsKey("f"));
282
283 Iterator<Map.Entry<String, String>> entryIterator = entries.iterator();
284 entryIterator.next();
285 entryIterator.remove();
286 assertFalse(underlying.containsKey("g"));
287
288 assertTrue(underlying.isEmpty());
289 assertTrue(map.isEmpty());
290 assertTrue(keys.isEmpty());
291 assertTrue(values.isEmpty());
292 assertTrue(entries.isEmpty());
293 }
294
295 public void testTransformEquals() {
296 Map<String, Integer> underlying = ImmutableMap.of("a", 0, "b", 1, "c", 2);
297 Map<String, Integer> expected
298 = Maps.transformValues(underlying, Functions.<Integer>identity());
299
300 assertMapsEqual(expected, expected);
301
302 Map<String, Integer> equalToUnderlying = Maps.newTreeMap();
303 equalToUnderlying.putAll(underlying);
304 Map<String, Integer> map = Maps.transformValues(
305 equalToUnderlying, Functions.<Integer>identity());
306 assertMapsEqual(expected, map);
307
308 map = Maps.transformValues(ImmutableMap.of("a", 1, "b", 2, "c", 3),
309 new Function<Integer, Integer>() {
310 @Override
311 public Integer apply(Integer from) {
312 return from - 1;
313 }
314 }
315 );
316 assertMapsEqual(expected, map);
317 }
318
319 public void testTransformEntrySetContains() {
320 Map<String, Boolean> underlying = Maps.newHashMap();
321 underlying.put("a", null);
322 underlying.put("b", true);
323 underlying.put(null, true);
324
325 Map<String, Boolean> map = Maps.transformValues(
326 underlying, new Function<Boolean, Boolean>() {
327 @Override
328 public Boolean apply(@Nullable Boolean from) {
329 return (from == null) ? true : null;
330 }
331 }
332 );
333
334 Set<Map.Entry<String, Boolean>> entries = map.entrySet();
335 assertTrue(entries.contains(Maps.immutableEntry("a", true)));
336 assertTrue(entries.contains(Maps.immutableEntry("b", (Boolean) null)));
337 assertTrue(entries.contains(
338 Maps.immutableEntry((String) null, (Boolean) null)));
339
340 assertFalse(entries.contains(Maps.immutableEntry("c", (Boolean) null)));
341 assertFalse(entries.contains(Maps.immutableEntry((String) null, true)));
342 }
343
344 @Override public void testKeySetRemoveAllNullFromEmpty() {
345 try {
346 super.testKeySetRemoveAllNullFromEmpty();
347 } catch (RuntimeException tolerated) {
348
349 }
350 }
351
352 @Override public void testEntrySetRemoveAllNullFromEmpty() {
353 try {
354 super.testEntrySetRemoveAllNullFromEmpty();
355 } catch (RuntimeException tolerated) {
356
357 }
358 }
359 }